<script setup lang="ts">
import { AddImagesButton, PostToTheSquare } from "@/api/drawing"
import ToTopPng from "@/assets/drawing/to_top.png"
import FlexScroll from "@/components/FlexScroll/index.vue"
import debounce from "@/utils/debounce"
import Speech from "@/utils/speech"
import { ElMessage, ElMessageBox } from "element-plus"
import Pubsub from "pubsub-js"
import { computed, onMounted, ref } from "vue"
import useCover from "../useCover"
import { DownImageList, DrawingDataProps, ImageButtonList } from "./type"

// const showImagePreview = ref<boolean>(false)
// const progress = ref<number>(1)
const imageVisible = ref<boolean>(false)
const u_v_loading = ref<boolean>(false)
const downloadBtnLoading = ref<boolean>(false)
// const showSrcList = ref<string[]>([''])
const previewImageInfo = ref<{ cos_url: string; id: number; cmd_proportion: string }>({
  cos_url: "",
  id: 1,
  cmd_proportion: ""
})
const flexScroll = ref(null)
const { loading, pagination, pageCount, handleImageDeleteId, coverList, immediate, initCoverDataList, nextPage } =
  useCover()

const toTop = () => {
  // @ts-ignore
  flexScroll.value && flexScroll.value.toTop()
}

const init = async () => {
  const list = await initCoverDataList("data")
  coverList.value = list
}

onMounted(() => {
  init()
  // Speech.instance.init()
  Pubsub.subscribe("UPDATE_DATA_INIT", async () => {
    await init()
    toTop()
  })

  Pubsub.subscribe("UPDATE_COVER_LIST", async () => {
    const list = await initCoverDataList("data")
    coverList.value = coverList.value.concat(list)
  })

  Speech.instance.on("image_progress", (msg: any) => {
    if (msg) {
      const match = String(msg.progress).match(/^(\d+)%$/)
      if (match) {
        const index = coverList.value.findIndex((item) => +item.id === +msg.image_id)

        if (index > -1) {
          console.log("index", index)
          coverList.value[index]["progress"] = Number(match[1])
          coverList.value = [...coverList.value]
        }
        // progress.value = Number(match[1])
      }
    }
  })

  Speech.instance.on("image", (msg: any) => {
    if (msg) {
      let timer: any = null
      timer = setTimeout(async () => {
        const list = await initCoverDataList("data")
        // await init()
        const index = list.findIndex((item: { id: string }) => +item.id === +msg.image_id)

        if (index > -1) {
          coverList.value[index] = list[index]
        }
        clearTimeout(timer)
      }, 2500)
    }
  })
})

// const handleClosePreview = () => {
//   showImagePreview.value = false
// }

const handleDownloadImage = debounce((src: string) => {
  // 开始下载前将按钮设置为加载状态
  downloadBtnLoading.value = true
  loading.value = true

  // 设置下载超时时间为 5 秒
  const downloadTimeout = setTimeout(() => {
    // 超时后将按钮状态设置为 false，并取消下载
    downloadBtnLoading.value = false
    loading.value = false
    ElMessage({
      type: "error",
      message: "下载超时，请稍后重试"
    })
    // 取消图片加载
    image.src = ""
  }, 5000)

  const image = new Image()
  image.crossOrigin = "Anonymous"
  image.onload = () => {
    // 清除下载超时计时器
    clearTimeout(downloadTimeout)
    const canvas = document.createElement("canvas")
    const ctx = canvas.getContext("2d")
    canvas.width = image.width
    canvas.height = image.height
    ctx && ctx.drawImage(image, 0, 0)

    canvas.toBlob(
      (blob: any) => {
        const link = document.createElement("a")
        link.href = URL.createObjectURL(blob)
        link.download = "photo"
        link.click()
        URL.revokeObjectURL(link.href)
        ElMessage({
          type: "success",
          message: "下载成功"
        })
        downloadBtnLoading.value = false
        loading.value = false
      },
      "image/png",
      0.9
    )
  }

  // 错误处理
  image.onerror = () => {
    // 清除下载超时计时器
    clearTimeout(downloadTimeout)
    downloadBtnLoading.value = false
    loading.value = false
    ElMessage({
      type: "error",
      message: "下载失败，请稍后重试"
    })
  }
  // 加载图片
  image.src = src
}, 200)

const handleImageClose = () => {
  imageVisible.value = false
  previewImageInfo.value.cos_url = ""
}

const handleChangeImgInfo = debounce(async (img: { id: number; path: string }, item: DrawingDataProps) => {
  if (["1"].includes(item.status)) {
    ElMessage({
      type: "warning",
      message: "图片正在生成中，请等候..."
    })
    return
  }

  if (img.id === 3) {
    await handleImageDeleteId(item.id)
    coverList.value = coverList.value.filter((source) => source.id !== item.id)
    ElMessage({
      type: "success",
      message: "删除成功"
    })
  } else if (img.id === 2) {
    // showImagePreview.value = true
    imageVisible.value = true
    previewImageInfo.value = {
      cos_url: item.cos_url,
      id: item.id,
      cmd_proportion: item.cmd_proportion
    }
  } else if (img.id === 1) {
    if (item.cos_url) {
      handleDownloadImage(item.cos_url)
    } else {
      ElMessage({
        type: "error",
        message: "图片路径不存在，无法下载..."
      })
      return
    }
  } else if (img.id === 99) {
    const confirm = await ElMessageBox.confirm("相关绘画图形将发布到绘画广场，是否继续发布？", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning"
    })
    if (confirm === "confirm") {
      try {
        const res = await PostToTheSquare({ id: item.id })
        if (res.code === 200) {
          ElMessage({
            type: "success",
            message: "发布成功，等待同款绘画列表更新..."
          })
          Pubsub.publish("UPDATE-SHINEE")
        }
      } catch (error) {
        ElMessage({
          type: "error",
          message: "发布失败"
        })
      }
    }
  } else return
}, 300)

const handleAddU_V_Button = debounce(async (id: number, btnLabel: string) => {
  try {
    u_v_loading.value = true
    const result = await AddImagesButton({ id, button: btnLabel })
    if (result.code === 200) {
      ElMessage({
        type: "success",
        message: "创建成功，等待绘画图片生成..."
      })
      Pubsub.publish("UPDATE_DATA_INIT")
    } else {
      ElMessage({
        type: "error",
        message: result.error
      })
    }
  } catch (error) {
    console.error(error)
  } finally {
    u_v_loading.value = false
  }
}, 300)

const imgStyle = computed(() => {
  return ["2:1", "16:9", "4:3"].includes(previewImageInfo.value.cmd_proportion)
    ? { width: "100%" }
    : { height: "490px" }
})
</script>

<template>
  <FlexScroll
    v-loading="loading"
    v-if="coverList.length > 0"
    ref="flexScroll"
    id="create"
    class="pic-flex-box"
    :immediate="immediate"
    :disabled="pagination.page >= pageCount"
    @scroll="nextPage"
  >
    <div class="data-content" v-for="item in coverList" :key="item.messages_id">
      <div class="info">
        <img
          class="image-viewer"
          :id="`image-${item.id}`"
          v-if="item.status === '2' && item.cos_url !== null && item.cos_url !== ''"
          :src="item.cos_url"
        />
        <div class="image-viewer wait" v-else>
          <div class="label">生成中</div>
          <el-progress :percentage="item.progress" :text-inside="false" :show-text="false" />
        </div>

        <!-- <el-image-viewer v-if="showImagePreview" v-bind:url-list="showSrcList" hide-on-click-modal teleported
          @close="handleClosePreview" style="z-index: 3000" /> -->

        <!-- 处理空字符串 -->
        <div class="label">
          {{
            String(item.command_base)
              .split(/[，,]{2,}/)
              .filter((item) => item !== "")
              .join("")
          }}
        </div>

        <div class="grid" :style="{ display: item.status === '1' || item.is_button === '0' ? 'none' : 'grid' }">
          <el-button
            class="btn"
            :disabled="u_v_loading"
            v-for="(btn, index) in ImageButtonList"
            :key="index"
            @click="handleAddU_V_Button(item.id, btn.button)"
          >
            {{ btn.button }}
          </el-button>
        </div>
      </div>

      <div class="down-list">
        <div
          :style="{ visibility: item.status === '1' ? 'hidden' : 'visible' }"
          :class="['list', img.id === 1 ? 'active' : '']"
          v-for="img in DownImageList"
          :title="img.title"
          :key="img.id"
          @click="handleChangeImgInfo(img, item)"
        >
          <img class="imgs" :src="img.path" alt="" />
        </div>
      </div>
    </div>
  </FlexScroll>

  <el-empty v-if="!loading && coverList.length <= 0" description="暂无数据" />

  <div v-if="coverList.length > 0" id="coverToTop" class="cover_to_top" @click="toTop" title="返回顶部">
    <img class="imgs" :src="ToTopPng" alt="" />
  </div>

  <el-dialog
    v-model="imageVisible"
    class="previewer-image-dialog"
    destroy-on-close
    @close="handleImageClose"
    v-if="imageVisible"
    title="查看原图"
    style="border-radius: 10px"
  >
    <img class="preview-img" :style="imgStyle" :src="previewImageInfo.cos_url" alt="" />

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleImageClose">取消</el-button>
        <el-button type="danger" :loading="downloadBtnLoading" @click="handleDownloadImage(previewImageInfo.cos_url)">
          下载
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.preview-img {
  /* width: 100%;
  height: 460px; */
  border-radius: 6px;
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 0 auto;
}

::v-deep .pic-flex-box {
  align-items: center;
}

.top {
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 9;
}

.cover_to_top {
  position: fixed;
  bottom: 40px;
  right: 40px;
  width: 40px;
  height: 40px;
  border-radius: 6px;
  display: flex;
  justify-content: center;
  align-items: center;
  background: var(--v3-body-bg-color);
  margin-bottom: 12px;
  cursor: pointer;

  .imgs {
    width: 24px;
    height: 24px;
  }
}

.data-content {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: flex-start;

  /* margin: 20px 0; */
  &:not(:last-child) {
    margin-bottom: 30px;
  }

  .down-list {
    height: 100%;
    display: flex;
    flex-direction: column;

    .list {
      width: 40px;
      height: 40px;
      border-radius: 6px;
      display: flex;
      justify-content: center;
      align-items: center;
      background: var(--v3-body-bg-color);
      margin-bottom: 12px;
      cursor: pointer;

      .imgs {
        width: 24px;
        height: 24px;
      }

      &.active {
        background: var(--el-color-primary);
      }
    }
  }

  .info {
    width: 100%;
    height: 100%;
    padding: 20px;
    border: 1px solid #e9e9e9;
    border-radius: 10px;
    margin-right: 12px;

    .label {
      color: var(--el-color-info);
      font-size: 14px;
      margin: 12px 0;
    }

    .image-viewer {
      width: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
      border-radius: 6px;
    }

    .wait {
      flex-direction: column;
      font-size: 14px;
      background: var(--v3-body-bg-color);
      color: #999;
      height: 300px;

      .ing {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
      }
    }
  }

  .btn {
    width: 66px;
    height: 40px;
    background: var(--v3-body-bg-color);
    border: unset !important;
    margin: 0 auto;
  }
}

::v-deep .el-progress--line {
  width: 160px;
}

.grid {
  display: grid;
  align-items: center;
  justify-items: center;
  grid-gap: 12px 12px;
  grid-template-columns: repeat(auto-fit, minmax(60px, 1fr));
}
</style>
